package com.dayuanit.service.impl;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dayuanit.dao.AddressDao;
import com.dayuanit.dao.GoodDao;
import com.dayuanit.dao.OrderDao;
import com.dayuanit.domain.Address;
import com.dayuanit.domain.Good;
import com.dayuanit.domain.Order;
import com.dayuanit.dto.OrderDTO;
import com.dayuanit.dto.SettleInfoDTO;
import com.dayuanit.exception.MallBusException;
import com.dayuanit.mallenum.OrderEnum;
import com.dayuanit.pay.domain.PayOrder;
import com.dayuanit.pay.service.PayService;
import com.dayuanit.service.OrderService;
import com.dayuanit.util.DateUtil;
import com.dayuanit.util.PageUtil;
import com.dayuanit.util.PriceUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class OrderServiceImpl implements OrderService {
	
	private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
	
	@Autowired
	private OrderDao orderDao;
	
	@Autowired
	private GoodDao goodDao;
	
	@Autowired
	private AddressDao addressDao;
	
	@Autowired
	private PayService payService;

	@Override
	public String addOrder(int goodId, int num, int userId, int addressId, int payType) {
		Order order = new Order();
		
		Good good = goodDao.getGood(goodId);
		Address address = addressDao.getAddressById(addressId);
		
		String amount = PriceUtil.mul(good.getPrice(), String.valueOf(num));
		order.setAmount(amount);
		order.setDeadTime(DateUtil.add(new Date(), 30));
		order.setGoodId(goodId);
		order.setNum(num);
		order.setStatus(OrderEnum.未支付.getStatus());
		order.setUnitPrice(good.getPrice());
		order.setUserId(userId);
		order.setAddress(address.getProvinceName() + " " + address.getCityName() + " " + address.getAreaName() + " " + address.getDetail());
		order.setPayType(payType);
		order.setPhone(address.getPhone());
		order.setRealName(address.getRealName());
		order.setGoodTile(good.getName());
		
		int rows = orderDao.addOrder(order);
		if (rows != 1){
			throw new MallBusException("订单提交失败");
		}
		
		//TODO 访问支付系统，获取支付页面地址
		PayOrder po = new PayOrder();
		po.setAmount(order.getAmount());
		po.setBizId(order.getId().toString());
		po.setDetailMsg("订单系统");
		
		po.setUserId(order.getUserId());
		po.setPayChannel(order.getPayType());
		
		Map<String, Object> map = payService.addPayOrder(po);
//		map.put("payOrderUrl", payUrl + "?payId=" + payOrder.getId());
//		map.put("payId", payOrder.getId());
//		map.put("success", true);
//		map.put("message", "");
		
		if (Boolean.parseBoolean(map.get("success").toString()) == false) {
			throw new MallBusException(map.get("message").toString());
		}
		
		System.out.println(map.get("payOrderUrl").toString());
		return map.get("payOrderUrl").toString();
	}
	
	@Override
	public SettleInfoDTO settleInfo(Integer goodId, Integer num) {
		Good good = goodDao.getGood(goodId);
		String amount = PriceUtil.mul(good.getPrice(), String.valueOf(num));
		
		SettleInfoDTO sid = new SettleInfoDTO();
		sid.setAmount(amount);
		sid.setDetail(good.getDetail());
		sid.setGoodTile(good.getName());
		sid.setImageUrl(good.getImageUrl());
		sid.setNum(num);
		sid.setUnitPrice(good.getPrice());
		sid.setGoodId(good.getId());
		return sid;
	}
	
	private static String requestPaySystemByHttpComment(Order order) throws Exception {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		
		HttpPost httpPost = new HttpPost("http://pay.dayuanit.com:8088/payOrder/createPayOrder.do");
		List <NameValuePair> nvps = new ArrayList <NameValuePair>();
		nvps.add(new BasicNameValuePair("amount", order.getAmount()));
		nvps.add(new BasicNameValuePair("userId", order.getUserId().toString()));
		nvps.add(new BasicNameValuePair("bizId", order.getId().toString()));
		nvps.add(new BasicNameValuePair("detailMsg", URLEncoder.encode("订单系统", "utf-8")));
		httpPost.setEntity(new UrlEncodedFormEntity(nvps));
		
		CloseableHttpResponse response = httpclient.execute(httpPost);
	    HttpEntity entity = (HttpEntity)response.getEntity();
	    String msg = EntityUtils.toString(entity);
		System.out.println(msg);
		return msg;
	}
	
	private String requestPaySystem(Order order) {
		try {
			URL url = new URL("http://pay.dayuanit.com:8088/payOrder/createPayOrder.do");
			URLConnection rulConnection = url.openConnection();
			HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;
			 httpUrlConnection.setDoOutput(true);
			 httpUrlConnection.setDoInput(true);
			 httpUrlConnection.setUseCaches(false);
			 httpUrlConnection.setRequestMethod("POST");
			 httpUrlConnection.connect();
			 
			 String param = "amount=" + order.getAmount() + "&userId="+ order.getUserId() + "&bizId="+order.getId() + "&detailMsg=" + URLEncoder.encode("订单系统", "utf-8");
			 
			 DataOutputStream dos=new DataOutputStream(httpUrlConnection.getOutputStream());
			 dos.writeBytes(param);
			 dos.flush();
			 dos.close();
			    
			 InputStream inStrm = httpUrlConnection.getInputStream();
			 BufferedReader bf = new BufferedReader(new InputStreamReader(inStrm, "utf-8"));
			 String msg = "";
			 String tmp = null;
			 while (null != (tmp = bf.readLine())) {
				 msg += tmp;
			 }
			 
			 System.out.println(msg);
			 ObjectMapper mapper = new ObjectMapper();
			String targetUrl = mapper.readTree(msg).findValue("data").findValue("payOrderUrl").asText();
			 return targetUrl;
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
		return null;
	}
	
	public static void main(String[] args) throws Exception {
		//requestPaySystemByHttpComment();
	}

	@Override
	public List<OrderDTO> listOrder(Integer userId, PageUtil pu) {
		List<Order> list = orderDao.listOrder(userId, pu.getStartNum(), PageUtil.PRE_PAGE_NUM);
		int total = orderDao.countOrders(userId);
		pu.setTotalCount(total);
		
		List<OrderDTO> orderDto = new ArrayList<OrderDTO>();
		
		for (Order order : list) {
			orderDto.add(createOrderDTO(order));
		}
		
		return orderDto;
	}

	@Override
	public void orderPaySuccess(Integer id) {
		Order order = orderDao.getOrder(id);
		if (null == order) {
			logger.info("订单"+id+" 不存在");
			return;
		}
		
		if (OrderEnum.已支付.getStatus() == order.getStatus().intValue()) {
			logger.info("订单"+id+"已经支付成功");
			return;
		}
		
		int rows = orderDao.modifyOrderStatus(id, order.getStatus(), OrderEnum.已支付.getStatus());
		if (1 != rows) {
			throw new MallBusException("订单状态修改失败");
		}
		
		//TODO 通知发货
	}

	@Override
	public int countOrder(Integer userId) {
		return orderDao.countOrders(userId);
	}
	
	@Override
	public OrderDTO getOrder(int id, int userId) {
		Order order = orderDao.getOrder(id);
		if (null == order) {
			throw new MallBusException("订单不存在");
		}
		
		if (order.getUserId().intValue() != userId) {
			throw new MallBusException("没有订单查看权限");
		}
		
		return createOrderDTO(order);
	}
	
	private OrderDTO createOrderDTO(Order order) {
		OrderDTO dto = new OrderDTO();
		dto.setAddress(order.getAddress());
		dto.setAmount(order.getAmount());
		dto.setCreateTime(DateUtil.dateToString(order.getCreateTime(), DateUtil.PATTERN_YYYY_MM_DD_HHMMSS));
		dto.setDeadTime(DateUtil.dateToString(order.getDeadTime(), DateUtil.PATTERN_YYYY_MM_DD_HHMMSS));
		dto.setGoodTile(order.getGoodTile());
		dto.setId(order.getId());
		dto.setModifyTime(DateUtil.dateToString(order.getModifyTime(), DateUtil.PATTERN_YYYY_MM_DD_HHMMSS));
		dto.setNum(order.getNum());
		dto.setPayType(payService.getPayName(order.getPayType()));
		dto.setPhone(order.getPhone());
		dto.setRealName(order.getRealName());
		dto.setStatus(order.getStatus());
		dto.setStatusDesc(OrderEnum.getOrderStatus(order.getStatus()).getDesc());
		dto.setUnitPrice(order.getUnitPrice());
		return dto;
	}

	@Override
	public String toPay(int orderId, int userId) {
		Order order = orderDao.getOrder(orderId);
		if (null == order) {
			throw new MallBusException("订单不存在");
		}
		
		if (userId != order.getUserId().intValue()) {
			throw new MallBusException("订单不属于你");
		}
		
		if (order.getStatus() != OrderEnum.未支付.getStatus()) {
			throw new MallBusException("订单无法支付");
		}
		
		PayOrder po = new PayOrder();
		po.setAmount(order.getAmount());
		po.setBizId(order.getId().toString());
		po.setDetailMsg("订单系统");
		
		po.setUserId(order.getUserId());
		po.setPayChannel(order.getPayType());
		
		Map<String, Object> map = payService.addPayOrder(po);
		
		if (Boolean.parseBoolean(map.get("success").toString()) == false) {
			throw new MallBusException(map.get("message").toString());
		}
		
		System.out.println(map.get("payOrderUrl").toString());
		return map.get("payOrderUrl").toString();
		
	}

}
